QuickDraw™ GX for the 68K swaps the application stack with its own to avoid using too much stack space in a graphics call. Developers who use Metrowerks 3.5 or Symantec C++ on the 68000 have trouble determining the GX function that caused a graphics debug string, notice, warning or error to be posted, because debugger and Macsbug stack crawls do not know how to traverse the GX stack. This version of GraphicsBug and the GX Graphics debugging init for the 68K support a stack crawl command (sc) that provides information about the last graphics function called as well as the application stack.
You can use GraphicsBug with the 1.0.1 version of QuickDraw GX without the GX Graphics debugging init to debug full performance applications as well, on the 68K. On the Power PC, use the normal version of the inits, libraries and GraphicsBug; these tools are not intended for the Power PC platform.
The supplied GX Graphics init and the file "graphics debugging library.c" have been modfied to call SysBreakStr instead of DebugStr so that MetroWerks can intercept these messages. This init works fine for THINK C as well; you'll still want to use the original "graphics debugging library.c" under THINK C. Calling SysBreakStr from a THINK C application causes both the THINK Debugger and MacsBug to receive a debugging message.
From MetroWerks, only the first error message generated by the init can be dealt with. If you try to continue, MetroWerks will likely fail with a bus error or by hanging. This is not a problem with the THINK Debugger; it appears that MetroWerks 3.5 has a problem in its debugger when an init generates a SysBreakStr error.
Here's some sample C++ code to show the type of situation where the stack crawl is helpful:
This function will fail with a "GRAPHICS ERROR: shape is nil" debugger message. The debugger will not be able to show the line that generated the error in the class member test. At that point, if you immediately run GraphicsBug you can get a stack crawl. If the debugging init is installed, you can select the correct heap with the application name (in this case, the application is named "sysbreak test.") Then, use the 'sc' command to get a stack crawl.
Note that GraphicsBug supplies the raw MacsBug name; it does not know how to generate the complete C++ name (which in this case for third would be "stuff::test(void).") It will work for old-style Macsbug names, however.
The test application turned validation on and off in main(). This is to prime the validation tables; without them, the stack crawl will show the dispatch number instead of the name, and will not be able to show the types of any of the parameters. Once the validation tables have been accessed, it is not necessary to prime them again until the machine is rebooted.
This works with and without the GX Graphics debugging init from both THINK C, C++, MetroWerks C, and C++ with both old and new style Macsbug names and with no names at all.
The correct heap must be selected for stack crawl to work. To select the correct heap without the debugging init, use the 'LC' command to List Clients:
(After typing 'hx ' you can use Command-mouse key to pick the heap number without cutting and pasting.)
There are a few functions for which this will not work, both GX functions and ones defined by the application. If the GX function does not require a graphics heap (such as GXPopGraphicsNotice) then the stack crawl will be unable to find the application stack. If the application function does not include the LINK and UNLK instructions, then the offset within the function will not be displayed. There are a number of other conditions to attempt to minimize the conditions under which the command generates a bus error or hangs: the A6 values must be even, smaller than A5, larger than each other, greater than zero, and so on.